<?php

namespace App\Admin\Controllers;

use App\Http\Controllers\Controller;
use App\Models\Test;
use App\Models\Unit;
use Dcat\Admin\Grid;
use Dcat\Admin\Layout\Column;
use Dcat\Admin\Layout\Content;
use Dcat\Admin\Layout\Row;
use Illuminate\Database\Eloquent\Collection;

class StatisticController extends Controller
{
    /**
     * @param Content $content
     * @return Content
     */
    public function index(Content $content)
    {
        // 超时未交卷的考试自动提交
        $this->autoSubmit();

        return $content
            ->header(trans('statistic.labels.statistics'))
            ->body(function (Row $row) {
                $row->column(6, function (Column $column) {
                    $column->row('<h4>单位排行</h4>');
                    $column->row($this->units());
                });

                $row->column(6, function (Column $column) {
                    $column->row('<h4>各单位人员排行</h4>');
                    $column->row($this->users());
                });
            });
    }

    /**
     * 单位排行
     *
     * @return string
     */
    protected function units()
    {
        // 参与人次
        $tests = Test::query()
            ->selectRaw('*, MAX(`test_score`) as max_score, MAX(`is_all_right`) as all_right')
            ->whereNotNull('submit_at')
            ->groupBy('user_id')
            ->get();

        // 非导出请求时更新单位统计
        if (! request()->has('_export_')) {
            $this->refreshUnitCount($tests);
        }

        $grid = Grid::make(Unit::query()->orderBy('average_score', 'desc'), function (Grid $grid) {
            $grid->number('排名（平均分）')->width(150);
            $grid->column('name');

            // 平均分
            $grid->column('average_score');

            // 参与率
            $grid->column('participate')->display(function () {
                /** @var Unit $this */
                if ($this->user_count && $this->test_count) {
                    return round($this->test_count / $this->user_count, 4) * 100;
                } else {
                    return 0;
                }
            })->append('%');

            // 满分率
            $grid->column('full_score')->display(function () {
                /** @var Unit $this */
                if ($this->test_count && $this->full_count) {
                    return round($this->full_count / $this->test_count, 4) * 100;
                } else {
                    return 0;
                }
            })->append('%');
        });

        // 一个页面暂时无法使用多个导出按钮
        // // 导出
        // $grid->export([
        //     'id' => '排名（平均分）',
        //     'name' => '名称',
        //     'average_score' => '平均分',
        //     'participate' => '参与率',
        //     'full_score' => '满分率',
        // ])->rows(function (array $rows) {
        //     foreach ($rows as $index => &$row) {
        //         $data = [
        //             'id' => $index + 1,
        //             'name' => $row['name'],
        //             'average_score' => $row['average_score'],
        //             'participate' => '0%',
        //             'full_score' => '0%',
        //         ];
        //
        //         // 参与率
        //         if ($row['user_count'] && $row['test_count']) {
        //             $data['participate'] = round($row['test_count'] / $row['user_count'], 4) * 100 . '%';
        //         }
        //
        //         // 满分率
        //         if ($row['test_count'] && $row['full_count']) {
        //             $data['full_score'] = round($row['full_count'] / $row['test_count'], 4) * 100 . '%';
        //         }
        //
        //         $row = $data;
        //     }
        //
        //     return $rows;
        // })->filename('单位排行-' . date('Ymd-His'));

        return $grid
            ->disableCreateButton()
            ->disableRowSelector()
            ->disableActions()
            ->render();
    }

    /**
     * 超时未交卷的考试自动提交
     */
    protected function autoSubmit()
    {
        Test::query()->whereNull('submit_at')->get()->map(function (Test $test) {
            if ($test->created_at->addMinutes($test->test_time)->lt(now())) {
                $test->submit();
            }
        });
    }

    /**
     * 各单位人员排行
     *
     * @return string
     */
    protected function users()
    {
        // 考试
        $tests = Test::with(['user', 'unit'])
            ->selectRaw('*, MAX(`test_score`) as max_score')
            ->whereNotNull('submit_at')
            ->groupBy('user_id')
            ->orderBy('max_score', 'desc');

        $grid = Grid::make($tests, function (Grid $grid) {
            $grid->column('排名（最高分）')->display(function () use ($grid) {
                return $grid->model()->getPerPage() * ($grid->model()->getCurrentPage() - 1) + $this->_index + 1;
            });

            $grid->column('user.name', '姓名');
            $grid->column('unit.name', '单位');
            $grid->column('max_score', '最高分');
        });

        // 过滤
        $grid->filter(function (Grid\Filter $filter) {
            $filter->equal('unit_id')->select(Unit::query()->pluck('name', 'id'));
        });

        // 导出
        $grid->export([
            'id' => '排名（最高分）',
            'name' => '姓名',
            'unit' => '单位',
            'score' => '最高分',
        ])->rows(function (array $rows) {
            foreach ($rows as $index => &$row) {
                $row = [
                    'id' => $index + 1,
                    'name' => $row['user']['name'],
                    'unit' => $row['unit']['name'],
                    'score' => $row['max_score'],
                ];
            }

            return $rows;
        })->filename('各单位人员排行-' . date('Ymd-His'));

        return $grid
            ->disableCreateButton()
            ->disableRowSelector()
            ->disableActions()
            ->render();
    }

    /**
     * 更新单位统计
     *
     * @param Unit[]|Collection $tests
     * @return Unit[]|Collection|\Illuminate\Support\Collection
     */
    protected function refreshUnitCount($tests)
    {
        return Unit::all()->map(function (Unit $unit) use ($tests) {
            // 无人单位不处理
            if (! $unit->user_count) {
                return $unit;
            }

            // 参加考试人数
            $unit->test_count = $tests->where('unit_id', $unit->id)->count();

            if ($unit->test_count) {
                // 满分人数
                $unit->full_count = $tests->where('unit_id', $unit->id)->where('all_right', true)->count();

                // 平均分
                $unit->average_score = $tests->where('unit_id', $unit->id)->sum('max_score') / $unit->test_count;
            }

            $unit->save();

            return $unit;
        });
    }
}
